package com.geek.factory.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.geek.factory.entity.StockCheckAdjustment;
import com.geek.factory.entity.StockCheckDetail;
import com.geek.factory.mapper.StockCheckAdjustmentMapper;
import com.geek.factory.service.IStockCheckAdjustmentService;
import com.geek.factory.service.IStockCheckDetailService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 库存盘点差异处理服务实现类
 * </p>
 *
 * @author author
 * @since 2025-06-29
 */
@Service
@Slf4j
public class StockCheckAdjustmentServiceImpl extends ServiceImpl<StockCheckAdjustmentMapper, StockCheckAdjustment> implements IStockCheckAdjustmentService {

    @Autowired
    private IStockCheckDetailService stockCheckDetailService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public StockCheckAdjustment createAdjustment(Integer detailId, String adjustmentType,
                                                BigDecimal adjustmentQuantity, String reason, String createdBy) {
        try {
            log.info("创建差异处理记录: detailId={}, adjustmentType={}, adjustmentQuantity={}, reason={}",
                    detailId, adjustmentType, adjustmentQuantity, reason);

            // 获取盘点明细信息
            StockCheckDetail detail = stockCheckDetailService.getById(detailId);
            if (detail == null) {
                log.error("盘点明细不存在: detailId={}", detailId);
                return null;
            }

            // 创建差异处理记录
            StockCheckAdjustment adjustment = new StockCheckAdjustment();
            adjustment.setDetailId(detailId);
            adjustment.setCheckId(detail.getCheckId());
            adjustment.setAdjustmentType(adjustmentType);
            adjustment.setAdjustmentQuantity(adjustmentQuantity);
            adjustment.setReason(reason);
            adjustment.setCreatedBy(createdBy);
            adjustment.setCreatedTime(LocalDateTime.now());
            adjustment.setUpdatedTime(LocalDateTime.now());

            // 保存记录
            boolean success = this.save(adjustment);
            if (!success) {
                log.error("保存差异处理记录失败");
                return null;
            }

            log.info("创建差异处理记录成功: adjustmentId={}", adjustment.getAdjustmentId());
            return adjustment;
        } catch (Exception e) {
            log.error("创建差异处理记录时发生异常", e);
            throw e;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean approveAdjustment(Integer adjustmentId, String approvedBy,
                                   String approvalResult, String approvalComments) {
        try {
            log.info("审批差异处理: adjustmentId={}, approvedBy={}, approvalResult={}",
                    adjustmentId, approvedBy, approvalResult);

            StockCheckAdjustment adjustment = this.getById(adjustmentId);
            if (adjustment == null) {
                log.error("差异处理记录不存在: adjustmentId={}", adjustmentId);
                return false;
            }

            // 检查是否已经审批
            if (adjustment.getApprovalResult() != null) {
                log.warn("差异处理记录已审批: adjustmentId={}, currentResult={}", 
                        adjustmentId, adjustment.getApprovalResult());
                return false;
            }

            // 更新审批信息
            adjustment.setApprovedBy(approvedBy);
            adjustment.setApprovalResult(approvalResult);
            adjustment.setApprovalComments(approvalComments);
            adjustment.setApprovedTime(LocalDateTime.now());
            adjustment.setUpdatedTime(LocalDateTime.now());

            boolean success = this.updateById(adjustment);
            log.info("更新差异处理审批结果: adjustmentId={}, success={}", adjustmentId, success);

            return success;
        } catch (Exception e) {
            log.error("审批差异处理时发生异常", e);
            throw e;
        }
    }

    @Override
    public Map<String, Object> getAdjustmentStats(Integer checkId) {
        try {
            Map<String, Object> stats = new HashMap<>();
            QueryWrapper<StockCheckAdjustment> wrapper = new QueryWrapper<>();
            wrapper.eq("check_id", checkId);

            // 总调整记录数
            long total = this.count(wrapper);
            stats.put("total", total);

            // 待审批数量
            wrapper.clear();
            wrapper.eq("check_id", checkId)
                    .isNull("approval_result");
            long pending = this.count(wrapper);
            stats.put("pending", pending);

            // 已审批通过数量
            wrapper.clear();
            wrapper.eq("check_id", checkId)
                    .eq("approval_result", "approved");
            long approved = this.count(wrapper);
            stats.put("approved", approved);

            // 已拒绝数量
            wrapper.clear();
            wrapper.eq("check_id", checkId)
                    .eq("approval_result", "rejected");
            long rejected = this.count(wrapper);
            stats.put("rejected", rejected);

            log.info("获取差异处理统计: checkId={}, total={}, pending={}, approved={}, rejected={}",
                    checkId, total, pending, approved, rejected);

            return stats;
        } catch (Exception e) {
            log.error("获取差异处理统计时发生异常", e);
            throw e;
        }
    }

    @Override
    public boolean isAdjustmentEditable(Integer adjustmentId) {
        try {
            StockCheckAdjustment adjustment = this.getById(adjustmentId);
            if (adjustment == null) {
                log.warn("差异处理记录不存在: adjustmentId={}", adjustmentId);
                return false;
            }

            // 只有未审批的记录可以修改
            boolean editable = adjustment.getApprovalResult() == null;
            log.info("检查差异处理是否可编辑: adjustmentId={}, editable={}", adjustmentId, editable);

            return editable;
        } catch (Exception e) {
            log.error("检查差异处理是否可编辑时发生异常", e);
            throw e;
        }
    }

    @Override
    public List<StockCheckAdjustment> getAdjustmentsByDetailId(Integer detailId) {
        try {
            QueryWrapper<StockCheckAdjustment> wrapper = new QueryWrapper<>();
            wrapper.eq("detail_id", detailId)
                    .orderByDesc("created_time");

            List<StockCheckAdjustment> adjustments = this.list(wrapper);
            log.info("查询明细的差异处理记录: detailId={}, count={}", detailId, adjustments.size());

            return adjustments;
        } catch (Exception e) {
            log.error("查询明细的差异处理记录时发生异常", e);
            throw e;
        }
    }

    @Override
    public List<StockCheckAdjustment> getAdjustmentsByCheckId(Integer checkId) {
        try {
            QueryWrapper<StockCheckAdjustment> wrapper = new QueryWrapper<>();
            wrapper.eq("check_id", checkId)
                    .orderByDesc("created_time");

            List<StockCheckAdjustment> adjustments = this.list(wrapper);
            log.info("查询盘点单的差异处理记录: checkId={}, count={}", checkId, adjustments.size());

            return adjustments;
        } catch (Exception e) {
            log.error("查询盘点单的差异处理记录时发生异常", e);
            throw e;
        }
    }
}
